package com.ipan.kits.jdbc;

import java.lang.reflect.Array;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

/**
 * JDBC工具类
 * 
 * @author iPan
 * @version 2018-02-13
 */
public class JdbcUtil {
	
//	public static void fillStatement(PreparedStatement stmt, Object[] params) {
//		if (params == null || params.length < 1) {
//			return;
//		}
//		try {
//			for (int i = 0; i < params.length; ++i) {
//				if (params[i] != null) {
//					stmt.setObject(i + 1, params[i]);
//				} else {
//					stmt.setNull(i + 1, Types.CHAR);
//				}
//			}
//		} catch (SQLException e) {
//			throw new RuntimeException(e);
//		}
//	}
	
	// 参考JFinal的处理
	// 测试当值为null的时候，不需要调用setNull；个别数据库不同，需要区分时间格式，调用fillStatementHandleDateType；
	public static void fillStatement(PreparedStatement pst, List<Object> paras) throws SQLException {
		for (int i=0, size=paras.size(); i<size; i++) {
			pst.setObject(i + 1, paras.get(i));
		}
	}
	
	public static void fillStatement(PreparedStatement pst, Object... paras) throws SQLException {
		for (int i=0; i<paras.length; i++) {
			pst.setObject(i + 1, paras[i]);
		}
	}
	
	/**
	 * fillStatement 时处理日期类型
	 */
	public static void fillStatementHandleDateType(PreparedStatement pst, List<Object> paras) throws SQLException {
		for (int i=0, size=paras.size(); i<size; i++) {
			Object value = paras.get(i);
			if (value instanceof java.util.Date) {
				if (value instanceof java.sql.Date) {
					pst.setDate(i + 1, (java.sql.Date)value);
				} else if (value instanceof java.sql.Timestamp) {
					pst.setTimestamp(i + 1, (java.sql.Timestamp)value);
				} else {
					// Oracle、SqlServer 中的 TIMESTAMP、DATE 支持 new Date() 给值
					java.util.Date d = (java.util.Date)value;
					pst.setTimestamp(i + 1, new java.sql.Timestamp(d.getTime()));
				}
			} else {
				pst.setObject(i + 1, value);
			}
		}
	}
	
	/**
	 * fillStatement 时处理日期类型
	 */
	public static void fillStatementHandleDateType(PreparedStatement pst, Object... paras) throws SQLException {
		for (int i=0; i<paras.length; i++) {
			Object value = paras[i];
			if (value instanceof java.util.Date) {
				if (value instanceof java.sql.Date) {
					pst.setDate(i + 1, (java.sql.Date)value);
				} else if (value instanceof java.sql.Timestamp) {
					pst.setTimestamp(i + 1, (java.sql.Timestamp)value);
				} else {
					// Oracle、SqlServer 中的 TIMESTAMP、DATE 支持 new Date() 给值
					java.util.Date d = (java.util.Date)value;
					pst.setTimestamp(i + 1, new java.sql.Timestamp(d.getTime()));
				}
			} else {
				pst.setObject(i + 1, value);
			}
		}
	}
	
	/**
	 * 关闭ResultSet、Statement、Connection对象
	 */
	public static void close(AutoCloseable obj) {
		if (obj != null) {
			try {
				obj.close();
			} catch (Exception e) {
			}
		}
	}
	
	// -- 数值包装 -- //
	// 不过滤特殊字符的场景
	public static String likeSql(String value) {
		return (value != null && value.length() > 0) ? "'%" + value.replace("'", "''") + "%'" : "";
	}
	public static String leftLinkSql(String value) {
		return (value != null && value.length() > 0) ? "'%" + value.replace("'", "''") + "'" : "";
	}
	public static String rightLinkSql(String value) {
		return (value != null && value.length() > 0) ? "'" + value.replace("'", "''") + "%'" : "";
	}
	public static String wrapSql(String value) {
		return (value != null && value.length() > 0) ? "'" + value + "'" : "''"; 
	}
	// 要过滤特殊字符的场景
	public static String likeSqlAndClear(String value) {
		return (value != null && value.length() > 0) ? "'%" + _clearSpecialChar(value) + "%'" : "";
	}
	public static String leftLinkSqlAndClear(String value) {
		return (value != null && value.length() > 0) ? "'%" + _clearSpecialChar(value) + "'" : "";
	}
	public static String rightLinkSqlAndClear(String value) {
		return (value != null && value.length() > 0) ? "'" + _clearSpecialChar(value) + "%'" : "";
	}
	public static String wrapSqlAndClear(String value) {
		return (value != null && value.length() > 0) ? "'" + _clearSpecialChar(value) + "'" : "''"; 
	}
	// 过滤特殊字符、空白、控制符
	public static String clearSpecialChar(String value) {
		return (value != null && value.length() > 0) ? _clearSpecialChar(value) : "";
	}
	private static String _clearSpecialChar(String value) { // 中间的空格暂没去掉
		return value.trim().replaceAll("[\\p{C}　\\s'\"\\\\]", "");
	}
	
	public static String inSql(Object... args) { 
		if (args == null || args.length < 1) {
			return "";
		}
		StringBuilder buf = new StringBuilder();
		if (args.length==1 && args[0].getClass().isArray()) { // args为Object引用的时候
			for (int i=0, len=Array.getLength(args[0]); i<len; ++i) {
				if (buf.length() > 0) {
					buf.append(", ");
				}
				Object o = Array.get(args[0], i);
                if (o instanceof Number) {
                    buf.append(o);
                } else {
                    buf.append(wrapSql(o.toString()));
                }
			}
		} else { // args为Object[]引用的时候
			for (Object o : args) {
				if (buf.length() > 0) {
					buf.append(", ");
				}
				if (o instanceof Number) {
					buf.append(o);
				} else {
					buf.append(wrapSql(o.toString()));
				}
			}
		}
		
		return buf.toString();
	}
	
	public static String wrapCountSql(String sql) {
		return "select count(*) from (" + sql + ") tmp"; 
	}
	
}
